import { FormItem, message, RadioButton, RadioGroup, Upload } from 'ant-design-vue'
import { defineComponent, nextTick, onMounted, ref, type HTMLAttributes } from 'vue'
import type { PropType } from 'vue'
import type { JsonSchema, Slots } from '../types'
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'
import { getProp } from '@/components/cms/utils'
import { formState } from '../mixins/useState'

export default defineComponent({
  inheritAttrs: true,
  emits: ['valueChange'],
  props: {
    schema: {
      type: Object as PropType<JsonSchema>,
      default: () => ({})
    },
    slots: {
      type: Object as PropType<Slots>,
      default: () => null
    }
  },
  setup(props, ctx) {
    const selected = ref(1)
    const template = ref(1)
    const fileList = ref<string[]>([])
    const loading = ref<boolean>(false)
    const imageUrl = ref<string | undefined>(undefined)

    const options = [
      { value: 1, label: 'logo模板' },
      { value: 2, label: '上传图片' }
    ]

    function getBase64(img: Blob, callback: (base64Url: string) => void) {
      const reader = new FileReader()
      reader.addEventListener('load', () => callback(reader.result as string))
      reader.readAsDataURL(img)
    }
    const beforeUpload = (file: any) => {
      loading.value = true
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/svg+xml'
      if (!isJpgOrPng) {
        loading.value = false
        message.error('You can only upload JPG file!')
        return false
      }
      const isLt1M = file.size / 1024 / 1024 < 1
      if (!isLt1M) {
        loading.value = false
        message.error('Image must smaller than 2MB!')
        return false
      }
      // Get this url from response in real world.
      getBase64(file, (base64Url: string) => {
        imageUrl.value = base64Url
        fileList.value = [base64Url]
        loading.value = false
      })
      return false
    }
    const handleChange = () => {
      if (!props.schema.field) {
        console.warn('字段没有传递')
        return
      }
      const value = {
        path: props.schema.field,
        value: {
          style: selected.value === 1 ? template.value : 1,
          image: selected.value === 2 ? imageUrl.value : ''
        }
      }
      ctx.emit('valueChange', value)
    }

    onMounted(() => {
      nextTick(() => {
        const value = getProp(formState.model, props.schema.field as string).value as { style: number; image: string }
        selected.value = imageUrl.value ? 2 : 1
        imageUrl.value = value?.style === 2 ? value.image : ''
      })
    })
    return () => {
      const logoList = props.schema?.logoList ?? {}
      const templateEl = (
        <RadioGroup onChange={() => handleChange()} v-model={[template.value, 'value']}>
          {Object.keys(logoList).map((item, index) => (
            <RadioButton class="logo-template" value={index + 1}>
              <div class="icon w-16 h-16 p-4">
                <img src={logoList[item]} />
              </div>
              <span class="title">模板{index + 1}</span>
            </RadioButton>
          ))}
        </RadioGroup>
      )
      const uploadEl = (
        <div class="flex flex-col gap-y-2">
          <Upload
            action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
            list-type="picture-card"
            before-upload={beforeUpload}
            showUploadList={false}
            class="logo-upload"
            v-model={[fileList.value, 'file-list']}
          >
            {imageUrl.value ? (
              <img class="w-full h-full" src={imageUrl.value} />
            ) : (
              <div>
                {loading.value ? <LoadingOutlined /> : <PlusOutlined />}
                <div class="text">上传图片</div>
              </div>
            )}
          </Upload>
          <small class="logo-upload__tips">建议尺寸200*88px，大小控制在1M以内</small>
        </div>
      )
      return (
        <div class="from-item-logo">
          <FormItem class="mb-2" label="设置logo" {...props.schema.props}>
            <RadioGroup v-model={[selected.value, 'value']} options={options} />
          </FormItem>
          <div {...(props.schema.props as HTMLAttributes)}>{selected.value === 1 ? templateEl : uploadEl}</div>
        </div>
      )
    }
  }
})
